﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		Отказ = Истина;
		ВызватьИсключение НСтр("ru = 'Операция не доступна в мобильном клиенте, используйте тонкий клиент.'");
	КонецЕсли;
	
	ТабличныеДокументыДляСравнения = ПолучитьИзВременногоХранилища(Параметры.АдресТабличныхДокументов);
	УдалитьИзВременногоХранилища(Параметры.АдресТабличныхДокументов);
	ТабличныйДокументЛевый = ПодготовитьТабличныйДокумент(ТабличныеДокументыДляСравнения.Левый);
	ТабличныйДокументПравый = ПодготовитьТабличныйДокумент(ТабличныеДокументыДляСравнения.Правый);
	
	Элементы.ГруппаЛевыйТабличныйДокумент.Заголовок = Параметры.ЗаголовокЛевый;
	Элементы.ГруппаПравыйТабличныйДокумент.Заголовок = Параметры.ЗаголовокПравый;
	
	Если Не ПустаяСтрока(Параметры.Заголовок) Тогда
		Заголовок = Параметры.Заголовок;
	КонецЕсли;
	
	СравнитьНаСервере();
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыТабличныйДокументЛевый

&НаКлиенте
Процедура ТабличныйДокументЛевыйПриАктивизации(Элемент)
	
	Если БлокировкаОбработкиАктивизации = Истина Тогда
		Возврат;
	КонецЕсли;
	
	Источник = Новый Структура("Объект, Элемент", ТабличныйДокументЛевый, Элементы.ТабличныйДокументЛевый);
	Приемник = Новый Структура("Объект, Элемент", ТабличныйДокументПравый, Элементы.ТабличныйДокументПравый);
	
	СоответствияИсточник = Новый Структура("Строки, Столбцы", СоответствиеСтрокЛевый, СоответствиеСтолбцовЛевый);
	СоответствияПриемник = Новый Структура("Строки, Столбцы", СоответствиеСтрокПравый, СоответствиеСтолбцовПравый);
	
	ОбработатьАктивизациюОбласти(Источник, Приемник, СоответствияИсточник, СоответствияПриемник);
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыТабличныйДокументПравый

&НаКлиенте
Процедура ТабличныйДокументПравыйПриАктивизации(Элемент)
	
	Если БлокировкаОбработкиАктивизации = Истина Тогда
		Возврат;
	КонецЕсли;
		
	Источник = Новый Структура("Объект, Элемент", ТабличныйДокументПравый, Элементы.ТабличныйДокументПравый);
	Приемник = Новый Структура("Объект, Элемент", ТабличныйДокументЛевый, Элементы.ТабличныйДокументЛевый);
	
	СоответствияИсточник = Новый Структура("Строки, Столбцы", СоответствиеСтрокПравый, СоответствиеСтолбцовПравый);
	СоответствияПриемник = Новый Структура("Строки, Столбцы", СоответствиеСтрокЛевый, СоответствиеСтолбцовЛевый);
	
	ОбработатьАктивизациюОбласти(Источник, Приемник, СоответствияИсточник, СоответствияПриемник);
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура КомандаПредыдущееИзменениеЛевый(Команда)
	
	ПредыдущееИзменение(Элементы.ТабличныйДокументЛевый, ТабличныйДокументЛевый, РазличияЯчеекЛевый);
	
КонецПроцедуры

&НаКлиенте
Процедура КомандаПредыдущееИзменениеПравый(Команда)
	
	ПредыдущееИзменение(Элементы.ТабличныйДокументПравый, ТабличныйДокументПравый, РазличияЯчеекПравый);
	
КонецПроцедуры

&НаКлиенте
Процедура КомандаСледующееИзменениеЛевый(Команда)
	
	СледующееИзменение(Элементы.ТабличныйДокументЛевый, ТабличныйДокументЛевый, РазличияЯчеекЛевый);
	
КонецПроцедуры

&НаКлиенте
Процедура КомандаСледующееИзменениеПравый(Команда)
	
	СледующееИзменение(Элементы.ТабличныйДокументПравый, ТабличныйДокументПравый, РазличияЯчеекПравый);
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Процедура СравнитьНаСервере()

	БлокировкаОбработкиАктивизации = Истина;
			
	СоответствиеСтрокЛевый = Новый СписокЗначений;
	СоответствиеСтрокПравый = Новый СписокЗначений;
	
	СоответствиеСтолбцовЛевый = Новый СписокЗначений;
	СоответствиеСтолбцовПравый = Новый СписокЗначений;
	
	РазличияЯчеекЛевый.Очистить();
	РазличияЯчеекПравый.Очистить();
	
	ВыполнитьСравнение();
	
	БлокировкаОбработкиАктивизации = Ложь;
	
КонецПроцедуры	

&НаСервере
Процедура ВыполнитьСравнение()
	
	#Область Сравнение
	
	// Тексты из ячеек табличных документов выгружается в таблицы значений.
	ТаблицаЛевогоДокумента = ПрочитатьТабличныйДокумент(ТабличныйДокументЛевый);
	ТаблицаПравогоДокумента = ПрочитатьТабличныйДокумент(ТабличныйДокументПравый);
	
	// Сравниваются табличные документы по строкам и подбираются соответствия строк.
	Соответствия = СформироватьСоответствия(ТаблицаЛевогоДокумента, ТаблицаПравогоДокумента, Истина);
	СоответствиеСтрокЛевый = Соответствия[0];
	СоответствиеСтрокПравый = Соответствия[1];
	
	// Сравниваются табличные документы по столбцам и подбираются соответствия столбцов.
	Соответствия = СформироватьСоответствия(ТаблицаЛевогоДокумента, ТаблицаПравогоДокумента, Ложь);
	СоответствиеСтолбцовЛевый = Соответствия[0];
	СоответствиеСтолбцовПравый = Соответствия[1];
	
	ТаблицаЛевогоДокумента = Неопределено;
	ТаблицаПравогоДокумента = Неопределено;
	
	#КонецОбласти
	
	#Область ГрафическоеОтображениеРазличий
	
	ЦветОбластиУдаленнойФон	= ЦветаСтиля.УдаленныйРеквизитФон;
	ЦветОбластиДобавленнойФон	= ЦветаСтиля.ДобавленныйРеквизитФон;
	ЦветОбластиИзмененнойФон	= ЦветаСтиля.ИзмененноеЗначениеРеквизитаФон;
	ЦветОбластиИзмененнойТекст	= ЦветаСтиля.ИзмененноеЗначениеРеквизитаЦвет;
		
	
	ВысотаЛевойТаблицы = ТабличныйДокументЛевый.ВысотаТаблицы;
	ШиринаЛевойТаблицы = ТабличныйДокументЛевый.ШиринаТаблицы;
	
	ВысотаПравойТаблицы = ТабличныйДокументПравый.ВысотаТаблицы;
	ШиринаПравойТаблицы = ТабличныйДокументПравый.ШиринаТаблицы;

	// Строки которые были удалены из левого табличного документа.
	Для НомерСтроки = 1 По СоответствиеСтрокЛевый.Количество()-1 Цикл
		
		Если СоответствиеСтрокЛевый[НомерСтроки].Значение = Неопределено Тогда
			
			Область = ТабличныйДокументЛевый.Область(НомерСтроки, 1, НомерСтроки, ШиринаЛевойТаблицы);
			Область.ЦветФона = ЦветОбластиУдаленнойФон;
			
			НоваяСтрокаРазличий = РазличияЯчеекЛевый.Добавить();
			НоваяСтрокаРазличий.НомерСтроки = НомерСтроки;
			НоваяСтрокаРазличий.НомерСтолбца = 0;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// Столбцы которые были удалены из левого табличного документа.
	Для НомерСтолбца = 1 По СоответствиеСтолбцовЛевый.Количество()-1 Цикл
		
		Если СоответствиеСтолбцовЛевый[НомерСтолбца].Значение = Неопределено Тогда
			
			Область = ТабличныйДокументЛевый.Область(1, НомерСтолбца, ВысотаЛевойТаблицы, НомерСтолбца);
			Область.ЦветФона = ЦветОбластиУдаленнойФон;
			
			НоваяСтрокаРазличий = РазличияЯчеекЛевый.Добавить();
			НоваяСтрокаРазличий.НомерСтроки = 0;
			НоваяСтрокаРазличий.НомерСтолбца = НомерСтолбца;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// Строки которые были добавлены в правый табличный документ.
	Для НомерСтроки = 1 По СоответствиеСтрокПравый.Количество()-1 Цикл
		
		Если СоответствиеСтрокПравый[НомерСтроки].Значение = Неопределено Тогда
			
			Область = ТабличныйДокументПравый.Область(НомерСтроки, 1, НомерСтроки, ШиринаПравойТаблицы);
			Область.ЦветФона = ЦветОбластиДобавленнойФон;
			
			НоваяСтрокаРазличий = РазличияЯчеекПравый.Добавить();
			НоваяСтрокаРазличий.НомерСтроки = НомерСтроки;
			НоваяСтрокаРазличий.НомерСтолбца = 0;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// Столбцы которые были добавлены в правый табличный документ.
	Для НомерСтолбца = 1 По СоответствиеСтолбцовПравый.Количество()-1 Цикл
		
		Если СоответствиеСтолбцовПравый[НомерСтолбца].Значение = Неопределено Тогда
			
			Область = ТабличныйДокументПравый.Область(1, НомерСтолбца, ВысотаПравойТаблицы, НомерСтолбца);
			Область.ЦветФона = ЦветОбластиДобавленнойФон;
			
			НоваяСтрокаРазличий = РазличияЯчеекПравый.Добавить();
			НоваяСтрокаРазличий.НомерСтроки = 0;
			НоваяСтрокаРазличий.НомерСтолбца = НомерСтолбца;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// Ячейки которые были изменены.
	Для НомерСтроки1 = 1 По СоответствиеСтрокЛевый.Количество()-1 Цикл
		
		НомерСтроки2 = СоответствиеСтрокЛевый[НомерСтроки1].Значение;
		Если НомерСтроки2 = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Для НомерСтолбца1 = 1 По СоответствиеСтолбцовЛевый.Количество()-1 Цикл
			
			НомерСтолбца2 = СоответствиеСтолбцовЛевый[НомерСтолбца1].Значение;
			Если НомерСтолбца2 = Неопределено Тогда
				Продолжить;
			КонецЕсли;
			
			Область1 = ТабличныйДокументЛевый.Область(НомерСтроки1, НомерСтолбца1, НомерСтроки1, НомерСтолбца1);
			Область2 = ТабличныйДокументПравый.Область(НомерСтроки2, НомерСтолбца2, НомерСтроки2, НомерСтолбца2);
			
			Если НЕ СравнитьОбласти(Область1, Область2) Тогда
				
				Область1 = ТабличныйДокументЛевый.Область(НомерСтроки1, НомерСтолбца1);
				Область2 = ТабличныйДокументПравый.Область(НомерСтроки2, НомерСтолбца2);
				
				Область1.ЦветТекста = ЦветОбластиИзмененнойТекст;
				Область2.ЦветТекста = ЦветОбластиИзмененнойТекст;
				
				Область1.ЦветФона = ЦветОбластиИзмененнойФон;
				Область2.ЦветФона = ЦветОбластиИзмененнойФон;
				
				
				НоваяСтрокаРазличий = РазличияЯчеекЛевый.Добавить();
				НоваяСтрокаРазличий.НомерСтроки = НомерСтроки1;
				НоваяСтрокаРазличий.НомерСтолбца = НомерСтолбца1;
				
				НоваяСтрокаРазличий = РазличияЯчеекПравый.Добавить();
				НоваяСтрокаРазличий.НомерСтроки = НомерСтроки2;
				НоваяСтрокаРазличий.НомерСтолбца = НомерСтолбца2;
				
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЦикла;
	
	РазличияЯчеекЛевый.Сортировать("НомерСтроки, НомерСтолбца");
	РазличияЯчеекПравый.Сортировать("НомерСтроки, НомерСтолбца");
	
	#КонецОбласти
	
КонецПроцедуры

&НаСервере
Функция СравнитьОбласти(Область1, Область2)
	
	Если Область1.Текст <> Область2.Текст Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если Область1.Примечание.Текст <> Область2.Примечание.Текст Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

&НаСервере
Функция ПрочитатьТабличныйДокумент(ТабличныйДокументИсточник)
	
	КоличествоСтолбцов = ТабличныйДокументИсточник.ШиринаТаблицы;
	
	Если КоличествоСтолбцов = 0 Тогда
		Возврат Новый ТаблицаЗначений;
	КонецЕсли;
	
	ТабличныйДокумент = Новый ТабличныйДокумент;
	Для НомерСтолбца = 1 По КоличествоСтолбцов Цикл
		ТабличныйДокумент.Область(1, НомерСтолбца, 1, НомерСтолбца).Текст = "Номер_" + Формат(НомерСтолбца,"ЧГ=0");
	КонецЦикла;
	
	ТабличныйДокумент.Вывести(ТабличныйДокументИсточник);
	
	Построитель = Новый ПостроительЗапроса;
	
	Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область());
	Построитель.Выполнить();
	ТаблицаЗначенийРезультат = Построитель.Результат.Выгрузить();
	
	Возврат ТаблицаЗначенийРезультат;
	
КонецФункции

&НаСервере
Функция СформироватьСоответствия(ТаблицаЛевая, ТаблицаПравая, ПоСтрокам)
	
	ДанныеИзТаблицыЛевая = ПолучитьДанныеДляСравнения(ТаблицаЛевая, ПоСтрокам);
	
	ДанныеИзТаблицыПравая = ПолучитьДанныеДляСравнения(ТаблицаПравая, ПоСтрокам);
	
	Если ПоСтрокам Тогда
		РезультатСоответствияЛевая = Новый СписокЗначений;
		РезультатСоответствияЛевая.ЗагрузитьЗначения(Новый Массив(ТаблицаЛевая.Количество()+1));
		
		РезультатСоответствияПравая = Новый СписокЗначений;
		РезультатСоответствияПравая.ЗагрузитьЗначения(Новый Массив(ТаблицаПравая.Количество()+1));		
		
	Иначе
		РезультатСоответствияЛевая = Новый СписокЗначений;
		РезультатСоответствияЛевая.ЗагрузитьЗначения(Новый Массив(ТаблицаЛевая.Колонки.Количество()+1));
		
		РезультатСоответствияПравая = Новый СписокЗначений;
		РезультатСоответствияПравая.ЗагрузитьЗначения(Новый Массив(ТаблицаПравая.Колонки.Количество()+1));
		
	КонецЕсли;
	
	ТекстЗапроса = "";
	
	ТекстЗапроса = ТекстЗапроса + "	ВЫБРАТЬ * ПОМЕСТИТЬ ТаблицаЛевая 
								|	ИЗ &ДанныеИзТаблицыЛевая КАК ДанныеИзТаблицыЛевая;" + Символы.ПС;
								
	ТекстЗапроса = ТекстЗапроса + "	ВЫБРАТЬ * ПОМЕСТИТЬ ТаблицаПравая
								|	ИЗ &ДанныеИзТаблицыПравая КАК ДанныеИзТаблицыПравая;" + Символы.ПС;
		
	ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ
	                              |	ТаблицаЛевая.Номер КАК НомерЭлементаЛевая,
	                              |	ТаблицаПравая.Номер КАК НомерЭлементаПравая,
	                              |	ВЫБОР
	                              |		КОГДА ТаблицаПравая.Номер - ТаблицаЛевая.Номер < 0
	                              |			ТОГДА ТаблицаЛевая.Номер - ТаблицаПравая.Номер
	                              |		ИНАЧЕ ТаблицаПравая.Номер - ТаблицаЛевая.Номер
	                              |	КОНЕЦ КАК РасстояниеОтНачала,
	                              |	ВЫБОР
	                              |		КОГДА &КоличествоСтрокПравая - ТаблицаПравая.Номер - (&КоличествоСтрокЛевая - ТаблицаЛевая.Номер) < 0
	                              |			ТОГДА &КоличествоСтрокЛевая - ТаблицаЛевая.Номер - (&КоличествоСтрокПравая - ТаблицаПравая.Номер)
	                              |		ИНАЧЕ &КоличествоСтрокПравая - ТаблицаПравая.Номер - (&КоличествоСтрокЛевая - ТаблицаЛевая.Номер)
	                              |	КОНЕЦ КАК РасстояниеОтКонца,
	                              |	СУММА(ВЫБОР
	                              |			КОГДА ТаблицаЛевая.Значение <> """"
	                              |				ТОГДА ВЫБОР
	                              |						КОГДА ТаблицаЛевая.Количество < ТаблицаПравая.Количество
	                              |							ТОГДА ТаблицаЛевая.Количество
	                              |						ИНАЧЕ ТаблицаПравая.Количество
	                              |					КОНЕЦ
	                              |			ИНАЧЕ 0
	                              |		КОНЕЦ) КАК КоличествоСовпаденийЗначений,
	                              |	СУММА(ВЫБОР
	                              |			КОГДА ТаблицаЛевая.Количество < ТаблицаПравая.Количество
	                              |				ТОГДА ТаблицаЛевая.Количество
	                              |			ИНАЧЕ ТаблицаПравая.Количество
	                              |		КОНЕЦ) КАК КоличествоСовпаденийВсего
	                              |ПОМЕСТИТЬ ДанныеСвернуто
	                              |ИЗ
	                              |	ТаблицаЛевая КАК ТаблицаЛевая
	                              |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаПравая КАК ТаблицаПравая
	                              |		ПО ТаблицаЛевая.Значение = ТаблицаПравая.Значение
	                              |
	                              |СГРУППИРОВАТЬ ПО
	                              |	ТаблицаЛевая.Номер,
	                              |	ТаблицаПравая.Номер
	                              |;
	                              |
	                              |////////////////////////////////////////////////////////////////////////////////
	                              |ВЫБРАТЬ
	                              |	ДанныеСвернуто.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
	                              |	ДанныеСвернуто.НомерЭлементаПравая КАК НомерЭлементаПравая,
	                              |	ДанныеСвернуто.КоличествоСовпаденийЗначений КАК КоличествоСовпаденийЗначений,
	                              |	ДанныеСвернуто.КоличествоСовпаденийВсего КАК КоличествоСовпаденийВсего,
	                              |	ВЫБОР
	                              |		КОГДА ДанныеСвернуто.РасстояниеОтНачала < ДанныеСвернуто.РасстояниеОтКонца
	                              |			ТОГДА ДанныеСвернуто.РасстояниеОтНачала
	                              |		ИНАЧЕ ДанныеСвернуто.РасстояниеОтКонца
	                              |	КОНЕЦ КАК МинимальноеРасстояние
	                              |ПОМЕСТИТЬ ДанныеСРасстояниями
	                              |ИЗ
	                              |	ДанныеСвернуто КАК ДанныеСвернуто
	                              |;
	                              |
	                              |////////////////////////////////////////////////////////////////////////////////
	                              |ВЫБРАТЬ
	                              |	ДанныеСРасстояниями.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
	                              |	ДанныеСРасстояниями.НомерЭлементаПравая КАК НомерЭлементаПравая,
	                              |	ДанныеСРасстояниями.КоличествоСовпаденийЗначений * МаксимумыПараметров.КоличествоСовпаденийВсего * МаксимумыПараметров.МинимальноеРасстояние + ДанныеСРасстояниями.КоличествоСовпаденийВсего * МаксимумыПараметров.МинимальноеРасстояние + (МаксимумыПараметров.МинимальноеРасстояние - ДанныеСРасстояниями.МинимальноеРасстояние) КАК Вес
	                              |ПОМЕСТИТЬ ВзвешенныеСовпадения
	                              |ИЗ
	                              |	ДанныеСРасстояниями КАК ДанныеСРасстояниями,
	                              |	(ВЫБРАТЬ
	                              |		МАКСИМУМ(ДанныеСРасстояниями.КоличествоСовпаденийВсего) КАК КоличествоСовпаденийВсего,
	                              |		МАКСИМУМ(ДанныеСРасстояниями.МинимальноеРасстояние) КАК МинимальноеРасстояние
	                              |	ИЗ
	                              |		ДанныеСРасстояниями КАК ДанныеСРасстояниями) КАК МаксимумыПараметров
	                              |;
	                              |
	                              |////////////////////////////////////////////////////////////////////////////////
	                              |ВЫБРАТЬ
	                              |	ЛучшееСовпадение.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
	                              |	ВзвешенныеСовпадения.НомерЭлементаПравая КАК НомерЭлементаПравая,
								  | ВзвешенныеСовпадения.Вес КАК Вес
	                              |ПОМЕСТИТЬ Соответствия
	                              |ИЗ
	                              |	(ВЫБРАТЬ
	                              |		ВзвешенныеСовпадения.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
	                              |		МАКСИМУМ(ВзвешенныеСовпадения.Вес) КАК Вес
	                              |	ИЗ
	                              |		ВзвешенныеСовпадения КАК ВзвешенныеСовпадения
	                              |	
	                              |	СГРУППИРОВАТЬ ПО
	                              |		ВзвешенныеСовпадения.НомерЭлементаЛевая) КАК ЛучшееСовпадение
	                              |		ЛЕВОЕ СОЕДИНЕНИЕ ВзвешенныеСовпадения КАК ВзвешенныеСовпадения
	                              |		ПО ЛучшееСовпадение.НомерЭлементаЛевая = ВзвешенныеСовпадения.НомерЭлементаЛевая
	                              |			И ЛучшееСовпадение.Вес = ВзвешенныеСовпадения.Вес";
	
		Запрос = Новый Запрос(ТекстЗапроса);
		Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
		Запрос.УстановитьПараметр("ДанныеИзТаблицыЛевая", ДанныеИзТаблицыЛевая);
		Запрос.УстановитьПараметр("ДанныеИзТаблицыПравая", ДанныеИзТаблицыПравая);
		Запрос.УстановитьПараметр("КоличествоСтрокЛевая", ТаблицаЛевая.Количество());
		Запрос.УстановитьПараметр("КоличествоСтрокПравая", ТаблицаПравая.Количество());
		Запрос.Выполнить();
		
		УровеньКонфликтов = 2;
		
		Пока УровеньКонфликтов > 0 Цикл
			Запрос.Текст = "ВЫБРАТЬ
			|	ВсеКонфликты.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	ВсеКонфликты.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|	СУММА(ВсеКонфликты.КоличествоКонфликтов) КАК КоличествоКонфликтов
			|ПОМЕСТИТЬ НайденныеКонфликты
			|ИЗ
			|	(ВЫБРАТЬ
			|		Соответствия.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|		Соответствия.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|		1 КАК КоличествоКонфликтов
			|	ИЗ
			|		Соответствия КАК Соответствия
			|			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Соответствия КАК Соответствия1
			|			ПО Соответствия.НомерЭлементаПравая < Соответствия1.НомерЭлементаПравая
			|			И Соответствия.НомерЭлементаЛевая > Соответствия1.НомерЭлементаЛевая
			|
			|	ОБЪЕДИНИТЬ ВСЕ
			|
			|	ВЫБРАТЬ
			|		Соответствия.НомерЭлементаЛевая,
			|		Соответствия.НомерЭлементаПравая,
			|		1
			|	ИЗ
			|		Соответствия КАК Соответствия
			|			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Соответствия КАК Соответствия1
			|			ПО Соответствия.НомерЭлементаПравая > Соответствия1.НомерЭлементаПравая
			|			И Соответствия.НомерЭлементаЛевая < Соответствия1.НомерЭлементаЛевая
			|
			|	ОБЪЕДИНИТЬ ВСЕ
			|
			|	ВЫБРАТЬ
			|		Соответствия.НомерЭлементаЛевая,
			|		Соответствия.НомерЭлементаПравая,
			|		1
			|	ИЗ
			|		(ВЫБРАТЬ
			|			Соответствия.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|			МАКСИМУМ(Соответствия.Вес) КАК Вес
			|		ИЗ
			|			Соответствия КАК Соответствия
			|		СГРУППИРОВАТЬ ПО
			|			Соответствия.НомерЭлементаПравая
			|		ИМЕЮЩИЕ
			|			КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Соответствия.НомерЭлементаЛевая) > 1) КАК Дубли
			|			ЛЕВОЕ СОЕДИНЕНИЕ Соответствия КАК Соответствия
			|			ПО Дубли.НомерЭлементаПравая = Соответствия.НомерЭлементаПравая
			|			И Дубли.Вес > Соответствия.Вес) КАК ВсеКонфликты
			|СГРУППИРОВАТЬ ПО
			|	ВсеКонфликты.НомерЭлементаЛевая,
			|	ВсеКонфликты.НомерЭлементаПравая
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	Соответствия.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	Соответствия.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|	Соответствия.Вес КАК Вес,
			|	ЕСТЬNULL(НайденныеКонфликты.КоличествоКонфликтов, 0) КАК КоличествоКонфликтов
			|ПОМЕСТИТЬ СоответствияСКонфликтами
			|ИЗ
			|	Соответствия КАК Соответствия
			|		ЛЕВОЕ СОЕДИНЕНИЕ НайденныеКонфликты КАК НайденныеКонфликты
			|		ПО Соответствия.НомерЭлементаЛевая = НайденныеКонфликты.НомерЭлементаЛевая
			|		И Соответствия.НомерЭлементаПравая = НайденныеКонфликты.НомерЭлементаПравая
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|УНИЧТОЖИТЬ Соответствия
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	СоответствияСКонфликтами.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	СоответствияСКонфликтами.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|	СоответствияСКонфликтами.Вес КАК Вес,
			|	СоответствияСКонфликтами.КоличествоКонфликтов КАК КоличествоКонфликтов
			|ПОМЕСТИТЬ ЗаменяемыеСоответствия
			|ИЗ
			|	(ВЫБРАТЬ
			|		МАКСИМУМ(СоответствияСКонфликтами.КоличествоКонфликтов) КАК КоличествоКонфликтов
			|	ИЗ
			|		СоответствияСКонфликтами КАК СоответствияСКонфликтами) КАК МаксимальноеКоличествоКонфликтов
			|		ЛЕВОЕ СОЕДИНЕНИЕ СоответствияСКонфликтами КАК СоответствияСКонфликтами
			|		ПО МаксимальноеКоличествоКонфликтов.КоличествоКонфликтов <> 0
			|		И СоответствияСКонфликтами.КоличествоКонфликтов = МаксимальноеКоличествоКонфликтов.КоличествоКонфликтов
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	СоответствияСКонфликтами.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	СоответствияСКонфликтами.НомерЭлементаПравая КАК КлючНомерЭлементаПравая,
			|	СоответствияСКонфликтами.КоличествоКонфликтов КАК КоличествоКонфликтов,
			|	ВариантыЗамены.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|	ВариантыЗамены.Вес КАК Вес
			|ПОМЕСТИТЬ ВариантыСоответствийДляЗамены
			|ИЗ
			|	ЗаменяемыеСоответствия КАК СоответствияСКонфликтами
			|		ЛЕВОЕ СОЕДИНЕНИЕ ВзвешенныеСовпадения КАК ВариантыЗамены
			|		ПО СоответствияСКонфликтами.НомерЭлементаЛевая = ВариантыЗамены.НомерЭлементаЛевая
			|		И СоответствияСКонфликтами.Вес > ВариантыЗамены.Вес
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	ВариантыСоответствийДляЗамены.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	ВариантыСоответствийДляЗамены.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|	1 КАК КоличествоКонфликтов
			|ПОМЕСТИТЬ НайденныеКонфликтыВариантов
			|ИЗ
			|	ВариантыСоответствийДляЗамены КАК ВариантыСоответствийДляЗамены
			|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ СоответствияСКонфликтами КАК СоответствияСКонфликтами
			|		ПО ВариантыСоответствийДляЗамены.НомерЭлементаПравая < СоответствияСКонфликтами.НомерЭлементаПравая
			|		И ВариантыСоответствийДляЗамены.НомерЭлементаЛевая > СоответствияСКонфликтами.НомерЭлементаЛевая
			|
			|ОБЪЕДИНИТЬ ВСЕ
			|
			|ВЫБРАТЬ
			|	ВариантыСоответствийДляЗамены.НомерЭлементаЛевая,
			|	ВариантыСоответствийДляЗамены.НомерЭлементаПравая,
			|	1
			|ИЗ
			|	ВариантыСоответствийДляЗамены КАК ВариантыСоответствийДляЗамены
			|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ СоответствияСКонфликтами КАК СоответствияСКонфликтами
			|		ПО ВариантыСоответствийДляЗамены.НомерЭлементаПравая > СоответствияСКонфликтами.НомерЭлементаПравая
			|		И ВариантыСоответствийДляЗамены.НомерЭлементаЛевая < СоответствияСКонфликтами.НомерЭлементаЛевая
			|
			|ОБЪЕДИНИТЬ ВСЕ
			|
			|ВЫБРАТЬ
			|	СоответствияСКонфликтами.НомерЭлементаЛевая,
			|	СоответствияСКонфликтами.НомерЭлементаПравая,
			|	1
			|ИЗ
			|	(ВЫБРАТЬ
			|		ВариантыСоответствийДляЗамены.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|		МАКСИМУМ(СоответствияСКонфликтами.Вес) КАК Вес
			|	ИЗ
			|		ВариантыСоответствийДляЗамены КАК ВариантыСоответствийДляЗамены
			|			ЛЕВОЕ СОЕДИНЕНИЕ СоответствияСКонфликтами КАК СоответствияСКонфликтами
			|			ПО ВариантыСоответствийДляЗамены.НомерЭлементаПравая = СоответствияСКонфликтами.НомерЭлементаПравая
			|	СГРУППИРОВАТЬ ПО
			|		ВариантыСоответствийДляЗамены.НомерЭлементаПравая) КАК Дубли
			|		ЛЕВОЕ СОЕДИНЕНИЕ СоответствияСКонфликтами КАК СоответствияСКонфликтами
			|		ПО Дубли.НомерЭлементаПравая = СоответствияСКонфликтами.НомерЭлементаПравая
			|		И Дубли.Вес > СоответствияСКонфликтами.Вес
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	ВариантыСоответствийДляЗамены.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	ВариантыСоответствийДляЗамены.КлючНомерЭлементаПравая КАК КлючНомерЭлементаПравая,
			|	ВариантыСоответствийДляЗамены.НомерЭлементаПравая КАК НомерЭлементаПравая,
			|	ВариантыСоответствийДляЗамены.Вес КАК Вес,
			|	ЕСТЬNULL(СУММА(Конфликты.КоличествоКонфликтов), 0) КАК КоличествоКонфликтов
			|ПОМЕСТИТЬ ВариантыСоответствийДляЗаменыСКонфликтами
			|ИЗ
			|	ВариантыСоответствийДляЗамены КАК ВариантыСоответствийДляЗамены
			|		ЛЕВОЕ СОЕДИНЕНИЕ НайденныеКонфликтыВариантов КАК Конфликты
			|		ПО ВариантыСоответствийДляЗамены.НомерЭлементаЛевая = Конфликты.НомерЭлементаЛевая
			|		И ВариантыСоответствийДляЗамены.НомерЭлементаПравая = Конфликты.НомерЭлементаПравая
			|СГРУППИРОВАТЬ ПО
			|	ВариантыСоответствийДляЗамены.НомерЭлементаЛевая,
			|	ВариантыСоответствийДляЗамены.КлючНомерЭлементаПравая,
			|	ВариантыСоответствийДляЗамены.НомерЭлементаПравая,
			|	ВариантыСоответствийДляЗамены.Вес,
			|	ВариантыСоответствийДляЗамены.КоличествоКонфликтов
			|ИМЕЮЩИЕ
			|	ВариантыСоответствийДляЗамены.КоличествоКонфликтов > ЕСТЬNULL(СУММА(Конфликты.КоличествоКонфликтов), 0)
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	ВариантыСоответствийДляЗаменыСКонфликтами.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	МАКСИМУМ(ВариантыСоответствийДляЗаменыСКонфликтами.Вес) КАК Вес
			|ПОМЕСТИТЬ МаксимальныйВесЗамены
			|ИЗ
			|	ВариантыСоответствийДляЗаменыСКонфликтами КАК ВариантыСоответствийДляЗаменыСКонфликтами
			|СГРУППИРОВАТЬ ПО
			|	ВариантыСоответствийДляЗаменыСКонфликтами.НомерЭлементаЛевая
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	ЗаменяемыеСоответствия.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	ЗаменяемыеСоответствия.НомерЭлементаПравая КАК КлючНомерЭлементаПравая,
			|	ЕСТЬNULL(ВариантыСоответствийДляЗаменыСКонфликтами.НомерЭлементаПравая, НЕОПРЕДЕЛЕНО) КАК НомерЭлементаПравая,
			|	ВариантыСоответствийДляЗаменыСКонфликтами.Вес КАК Вес
			|ПОМЕСТИТЬ СоответствияДляЗамены
			|ИЗ
			|	ЗаменяемыеСоответствия КАК ЗаменяемыеСоответствия
			|		ЛЕВОЕ СОЕДИНЕНИЕ МаксимальныйВесЗамены КАК МаксимальныйВесЗамены
			|		ПО ЗаменяемыеСоответствия.НомерЭлементаЛевая = МаксимальныйВесЗамены.НомерЭлементаЛевая
			|		ЛЕВОЕ СОЕДИНЕНИЕ ВариантыСоответствийДляЗаменыСКонфликтами КАК ВариантыСоответствийДляЗаменыСКонфликтами
			|		ПО ВариантыСоответствийДляЗаменыСКонфликтами.Вес = МаксимальныйВесЗамены.Вес
			|		И ВариантыСоответствийДляЗаменыСКонфликтами.НомерЭлементаЛевая = МаксимальныйВесЗамены.НомерЭлементаЛевая
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	СоответствияСКонфликтами.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
			|	ЕСТЬNULL(СоответствияДляЗамены.НомерЭлементаПравая, СоответствияСКонфликтами.НомерЭлементаПравая) КАК
			|		НомерЭлементаПравая,
			|	ЕСТЬNULL(СоответствияДляЗамены.Вес, СоответствияСКонфликтами.Вес) КАК Вес,
			|	СоответствияСКонфликтами.КоличествоКонфликтов КАК КоличествоКонфликтов
			|ПОМЕСТИТЬ Соответствия
			|ИЗ
			|	СоответствияСКонфликтами КАК СоответствияСКонфликтами
			|		ЛЕВОЕ СОЕДИНЕНИЕ СоответствияДляЗамены КАК СоответствияДляЗамены
			|		ПО СоответствияСКонфликтами.НомерЭлементаЛевая = СоответствияДляЗамены.НомерЭлементаЛевая
			|		И СоответствияСКонфликтами.НомерЭлементаПравая = СоответствияДляЗамены.КлючНомерЭлементаПравая
			|ГДЕ
			|	СоответствияДляЗамены.НомерЭлементаПравая ЕСТЬ NULL
			|	ИЛИ СоответствияДляЗамены.НомерЭлементаПравая <> НЕОПРЕДЕЛЕНО
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	ЕСТЬNULL(МАКСИМУМ(СоответствияСКонфликтами.КоличествоКонфликтов), 0) КАК КоличествоКонфликтов
			|ИЗ
			|	СоответствияСКонфликтами КАК СоответствияСКонфликтами";
			
		Выборка = Запрос.Выполнить().Выбрать(); //@skip-check query-in-loop - Итерационная обработка таблицы
		Выборка.Следующий();
		УровеньКонфликтов = Выборка.КоличествоКонфликтов;
		
		ВременныеТаблицыКУдалению = Новый Массив;
		ВременныеТаблицыКУдалению.Добавить("СоответствияДляЗамены");
		ВременныеТаблицыКУдалению.Добавить("ВариантыСоответствийДляЗаменыСКонфликтами");
		ВременныеТаблицыКУдалению.Добавить("ВариантыСоответствийДляЗамены");
		ВременныеТаблицыКУдалению.Добавить("СоответствияСКонфликтами");
		ВременныеТаблицыКУдалению.Добавить("ЗаменяемыеСоответствия");
		ВременныеТаблицыКУдалению.Добавить("НайденныеКонфликты");
		ВременныеТаблицыКУдалению.Добавить("МаксимальныйВесЗамены");
		ВременныеТаблицыКУдалению.Добавить("НайденныеКонфликтыВариантов");
		
		УдалитьВременныеТаблицы(Запрос, ВременныеТаблицыКУдалению); //@skip-check query-in-loop - Итерационная обработка таблицы

	КонецЦикла;
	
	Запрос.Текст = "ВЫБРАТЬ
	               |	Соответствия.НомерЭлементаЛевая КАК НомерЭлементаЛевая,
	               |	Соответствия.НомерЭлементаПравая КАК НомерЭлементаПравая
	               |ИЗ
	               |	Соответствия КАК Соответствия";
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Пока Выборка.Следующий() Цикл
		Если РезультатСоответствияЛевая[Выборка.НомерЭлементаЛевая].Значение = Неопределено
			И РезультатСоответствияПравая[Выборка.НомерЭлементаПравая].Значение = Неопределено Тогда
				РезультатСоответствияЛевая[Выборка.НомерЭлементаЛевая].Значение = Выборка.НомерЭлементаПравая;
				РезультатСоответствияПравая[Выборка.НомерЭлементаПравая].Значение = Выборка.НомерЭлементаЛевая;
		КонецЕсли;
	КонецЦикла;
	
	Результат = Новый Массив;
	Результат.Добавить(РезультатСоответствияЛевая);
	Результат.Добавить(РезультатСоответствияПравая);
	
	Возврат Результат;

КонецФункции

&НаСервере
Функция ПолучитьДанныеДляСравнения(ТаблицаЗначенийИсточник, ПоСтрокам)
	
	МаксимальныйРазмерСтрок = Новый КвалификаторыСтроки(100);
	
	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("Номер",		Новый ОписаниеТипов("Число"));
	Результат.Колонки.Добавить("Значение",	Новый ОписаниеТипов("Строка", , МаксимальныйРазмерСтрок));
	
	Граница1 = ?(ПоСтрокам, ТаблицаЗначенийИсточник.Количество(),
							ТаблицаЗначенийИсточник.Колонки.Количество()) - 1;
		
	Граница2 = ?(ПоСтрокам, ТаблицаЗначенийИсточник.Колонки.Количество(),
							ТаблицаЗначенийИсточник.Количество()) - 1;
		
	Для Индекс1 = 0 По Граница1 Цикл
		
		Для Индекс2 = 0 По Граница2 Цикл
			
			НоваяСтрока = Результат.Добавить();
			НоваяСтрока.Номер = Индекс1+1;
			НоваяСтрока.Значение = ?(ПоСтрокам, ТаблицаЗначенийИсточник[Индекс1][Индекс2],
												ТаблицаЗначенийИсточник[Индекс2][Индекс1]);
			
		КонецЦикла;
		
	КонецЦикла;

	Результат.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
	Результат.ЗаполнитьЗначения(1, "Количество");
	
	Результат.Свернуть("Номер, Значение", "Количество");
	
	Возврат Результат;
		
КонецФункции


&НаКлиенте
Процедура ОбработатьАктивизациюОбласти(ТабДокИсточник, ТабДокПриемник, СоответствияИсточник, СоответствияПриемник)
	
	БлокировкаОбработкиАктивизации = Истина;
	
	ТекОбласть = ТабДокИсточник.Элемент.ТекущаяОбласть;
	
	Если ТекОбласть.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Таблица Тогда
		
		ВыбраннаяОбласть = ТабДокПриемник.Область();
		
	Иначе
	
		Если ТекОбласть.Низ < СоответствияИсточник.Строки.Количество() Тогда
			НомерСтроки = СоответствияИсточник.Строки[ТекОбласть.Низ].Значение;
		Иначе
			НомерСтроки = ТекОбласть.Низ 
							- СоответствияИсточник.Строки.Количество()
								+ СоответствияПриемник.Строки.Количество();
		КонецЕсли;
		
		Если ТекОбласть.Лево < СоответствияИсточник.Столбцы.Количество() Тогда
			НомерСтолбца = СоответствияИсточник.Столбцы[ТекОбласть.Лево].Значение;
		Иначе
			НомерСтолбца = ТекОбласть.Лево
							- СоответствияИсточник.Столбцы.Количество()
								+ СоответствияПриемник.Столбцы.Количество();
		КонецЕсли;
		
		
		ВыбраннаяОбласть = Неопределено;
		
		Если ТекОбласть.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда
					
			Если НомерСтроки <> Неопределено И НомерСтолбца <> Неопределено Тогда
				ВыбраннаяОбласть = ТабДокПриемник.Объект.Область(НомерСтроки, НомерСтолбца);
			КонецЕсли;
					
		ИначеЕсли ТекОбласть.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Строки Тогда
			
			Если НомерСтроки <> Неопределено Тогда
				ВыбраннаяОбласть = ТабДокПриемник.Объект.Область(НомерСтроки, 0, НомерСтроки, 0);
			КонецЕсли;
			
		ИначеЕсли ТекОбласть.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Колонки Тогда
			
			Если НомерСтолбца <> Неопределено Тогда
				ВыбраннаяОбласть = ТабДокПриемник.Объект.Область(0, НомерСтолбца, 0, НомерСтолбца);
			КонецЕсли;
			
		Иначе		
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	ТабДокПриемник.Элемент.ТекущаяОбласть = ВыбраннаяОбласть;
	
	БлокировкаОбработкиАктивизации = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура ПредыдущееИзменение(ЭлементФормы, РеквизитФормы, ТаблицаРазличий)
	
	Перем Индекс;
	
	ТекЯчейка = ЭлементФормы.ТекущаяОбласть;
	НомерСтроки = ТекЯчейка.Верх;
	НомерСтолбца = ТекЯчейка.Лево;
	Для Каждого ТекСтрока Из ТаблицаРазличий Цикл
		Если ТекСтрока.НомерСтроки < НомерСтроки 
			ИЛИ ТекСтрока.НомерСтроки = НомерСтроки И ТекСтрока.НомерСтолбца < НомерСтолбца Тогда
			Индекс = ТаблицаРазличий.Индекс(ТекСтрока);
		ИначеЕсли ТекСтрока.НомерСтроки >= НомерСтроки И ТекСтрока.НомерСтолбца > НомерСтолбца Тогда
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если Индекс <> Неопределено Тогда
		СтрокаРазличий = ТаблицаРазличий[Индекс];
		НомерСтроки = СтрокаРазличий.НомерСтроки;
		НомерСтолбца = СтрокаРазличий.НомерСтолбца;
		ЭлементФормы.ТекущаяОбласть = РеквизитФормы.Область(НомерСтроки, НомерСтолбца, НомерСтроки, НомерСтолбца);
	КонецЕсли;
	
	
КонецПроцедуры

&НаКлиенте
Процедура СледующееИзменение(ЭлементФормы, РеквизитФормы, ТаблицаРазличий)
	
	Перем Индекс;
	
	ТекЯчейка = ЭлементФормы.ТекущаяОбласть;
	НомерСтроки = ТекЯчейка.Верх;
	НомерСтолбца = ТекЯчейка.Лево;
	Для Каждого ТекСтрока Из ТаблицаРазличий Цикл
		Если ТекСтрока.НомерСтроки = НомерСтроки И ТекСтрока.НомерСтолбца > НомерСтолбца 
			ИЛИ ТекСтрока.НомерСтроки > НомерСтроки Тогда
			Индекс = ТаблицаРазличий.Индекс(ТекСтрока);
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если Индекс <> Неопределено Тогда
		СтрокаРазличий = ТаблицаРазличий[Индекс];
		НомерСтроки = СтрокаРазличий.НомерСтроки;
		НомерСтолбца = СтрокаРазличий.НомерСтолбца;
		ЭлементФормы.ТекущаяОбласть = РеквизитФормы.Область(НомерСтроки, НомерСтолбца, НомерСтроки, НомерСтолбца);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция ПодготовитьТабличныйДокумент(ТабличныйДокумент)
	
	Если ТипЗнч(ТабличныйДокумент) = Тип("ТабличныйДокумент") Тогда
		Возврат ТабличныйДокумент;
	КонецЕсли;
	
	ДвоичныеДанные = ПолучитьИзВременногоХранилища(ТабличныйДокумент); // ДвоичныеДанные - 
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("mxl");
	ДвоичныеДанные.Записать(ИмяВременногоФайла);
	
	Результат = Новый ТабличныйДокумент;
	Результат.Прочитать(ИмяВременногоФайла);
	
	УдалитьФайлы(ИмяВременногоФайла);
	
	Возврат Результат;

КонецФункции

&НаСервере
Процедура УдалитьВременныеТаблицы(Запрос, Таблицы)
	Запрос.Текст = "УНИЧТОЖИТЬ " + СтрСоединить(Таблицы, "; УНИЧТОЖИТЬ ");
	Запрос.Выполнить();
КонецПроцедуры

#КонецОбласти